iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
自我挑戰組

一個令我自豪的App完成之路系列 第 12

Firebase來幫忙資料上傳 Day 12

  • 分享至 

  • xImage
  •  

將資料上傳至Firebase上

使用UIImagePikerController來選取照片上傳

  • 使用UINavigationControllerDelegate
    • 導向拍照或是相簿的畫面
  • 使用UIImagePickerControllerDelegate
    • 照片拍下來之後的動作

做一個UIAlertController來挑選要使用的方式

// 產生一個UIImagePickerController的控制器
let imagePicker = UIImagePickerController()

// 先點ImageView屬性欄位的User Interaction Enabled
// 新增一個Tap Gesture Recognizer套用到ImageView上
// 將ViewController連結Tap Gesture Recognizer的動作上,將連結方式選擇為@IBAction

@IBAction func addimage(_ sender: UIGestureRecognizer){

	let controller = UIAlertController(title: "選取上傳方式", message: nil, preferredStyle: .alert)
	let controllerAction_camera = UIAlertAction(title: "相機", style: .default){(_ ) in
            self.cameraTake()
      }
	let controllerAction_gallery = UIAlertAction(title: "相簿", style: .default, handler: {(_ ) in
            self.galleryUse()})
	let controllerAction_cancel = UIAlertAction(title: "取消", style: .cancel, handler: nil)
        
	controller.addAction(controllerAction_camera)
	controller.addAction(controllerAction_gallery)
	controller.addAction(controllerAction_cancel)
        
	self.present(controller, animated: true, completion: nil)

}

// 使用Function讓程式碼更加容易讀
func cameraTake(){
				// 選擇ImagePickerController的類型
        imagePicker.sourceType = .camera
        self.present(imagePicker, animated: true, completion: nil)
				}
    
func galleryUse(){
        imagePicker.sourceType = .photoLibrary
        self.present(imagePicker, animated: true, completion: nil)
				}

override func viewDidLoad() {
			super.viewDidLoad()
			// 將imagePicker控制器的指派透過現在這個ViewController來執行
			imagePicker.delegate = self
			}

// UIImagePickerControllerDelegate讓資料知道會用哪種方式來儲存
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // 這邊選擇使用原相機儲存,且將圖片顯示在ImageView
				if let image = info[.originalImage] as? UIImage {
                    self.addimage.image = image
        }
                
                picker.dismiss(animated: true)
		 }

開啟隱私權設定

打開Info.plist

按下+

輸入Privacy - Camera Usage Description

輸入Privacy - Photo Library Usage Description

為什麼輸入這個?

因為iOS的隱私設定,如果沒有這兩項說明沒有辦法啟動我的相機與相簿

將剛剛輸入的資料上傳到Firebase

安裝Firebase/Database

pod 'Firebase/Database'

pod install

新增文字資料到網路上

import FirebaseDatabase

// 新增一個add的按鈕,並連結到這個ViewController
@IBAction func addbutton(_ sender: Any) {
        
				// 在Firebase上傳資料需要有一個refence(),故新增一個
        let ref = Database.database().reference()
        
        // child(" ")表示生成一個分支叫" "
				// childByAutoId()表示會自動生成一個ID編碼
				// setValue()是上傳的主要function
        ref.child("BookName").childByAutoId().setValue(AddBookName.text)
        ref.child("BookAuthor").childByAutoId().setValue(AddBookAuthor.text)
        ref.child("BookISBN").childByAutoId().setValue(AddBookISBN.text)
        ref.child("BookImage").childByAutoId().setValue(addimage.image)
        
    }

成果展示:

https://i.imgur.com/Bez0eds.png

https://i.imgur.com/0zZjCKl.png

補充:

後來發現如果使用AutoId我根本很難去提取資料,所以我要將我的書名命名

下面補上,後來做的修改

我希望我的資料是透過一個名為Book的Structure上傳到網路上

那麼我應該做出這樣的修改:

先新增一個Swift文件,名為Book

import Foundation
import Firebase

class Book{
	var booktitle:String
	var bookauthors:String
	var bookISBN:String
	var bookimage:[String]?
	var key:String
	var ref:DataBaseReference?

	// 自己從程式內部輸入進資料
	// 將外部(textfield)的這些輸入到Book這個Struture內變數
	init(booktitle:String,bookauthors:String,bookISBN:String,bookimage:[String],key:String = ""){
			self.key = key
			self.booktitle = booktitle
			self.bookauthors = bookauthors
			self.bookISBN = bookISBN
			self.bookimage = bookimage
			self.ref = nil
	}

	// 當從網路上抓下來的檔案,輸入進資料
	init(snapshot:DataSnapshot){
			key = snapshot.key
			let snapshotValue = snapshot.value as![String:AnyObject]
			booktitle = snapshotValue["booktitle"] as! String
			bookauthors = snapshotValue["bookauthors"] as! String
			bookISBN = snapshotValue["bookISBN"] as! String
			bookimage = snapshotValue["bookimage"] as? [String]
			ref = snapshot.ref
	}
	

// 因為上傳資料,需要將其變成字典的形式
// 所以將Book變成字典的形式
	func becomeDictionary() -> Any{
			return ["booktitle":booktitle,
							"bookauthors":bookauthors,
							"bookISBN":bookISBN,
							"bookimage":bookimage
							]
	}

原本的addButton也會開始做很多事情

func addbutton(){

// 將剛剛資料輸入進Book struture
let book = Book(booktitle:AddBookName.text!,bookauthors:AddBookAuthors.text,
								bookISBN:AddBookISBN.text,bookimage:[""])
// 將剛剛的資料上傳到Firebase
self.uploadtoFirebase(value:book)

}
func uploadtoFirebase(values:Book){
	// 首先先用每個Book的名字創造一個類似資料夾的東西,來存放每本書的資料
	let bookItemRef = self.ref!.child(values.booktitle.lowercased())
	// 因為要上傳圖片,我們需要一個Storage的ref
	// 一樣根據書名,做一個類似資料夾的東西
	let storageImageRef = Storage.storage().reference().child("BookRentImage").child((values.booktitle))

	// 當我們要上傳的時候,有鑒於上傳圖片跟上傳一些文字資料的速度並不一樣,所以在這邊先做一個辨認
	// 如果有的話,則新增一個在書名的資料夾內
	if addimage.image != nil{
		let uploadTask = StorageImageRef.child("\(values.booktitle).jpeg").putData(self.ImageData!,metadata:nil,completion:{(data,error) in 
				if error != nil{
					print("Error",error.localizedDescription)
					return
				}
		})

DispatchQueue.global(qos:.userInitiated).async{
		uploadTask.observe(.success,handler:{(snapshot) in
			storageImageRef.child("\(values.booktitle).jpeg").downloadURL{(url,error) in
				if let error = error{
						print("Error",error.localizedDescription)
				}else{
				
					if let imageFileURL = url.absoluteString{
									// 檢查是不是所上傳的URL
									print("This is my imageURL",imageURL)
					// 如果沒有問題,那麼將上傳圖片所產生的URL也一併上傳
					let bookItem = Book(booktitle:values.booktitle,bookauthors:values.bookauthors,bookISBN:values.bookISBN,bookimage:imageURL)
					bookItemRef.setValue(bookItem.becomeDictionary(),withCompletionBlock:{(error,ref) in 
							if error == nil{
								print("Success")
							}
					// 如果要加上UIAlertController加在這邊
					}
				}
		}
}

大功告成!

https://i.imgur.com/Q0cjP44.gif

https://i.imgur.com/z5MYbSQ.png

參考網址:

Swift & Firebase DB(Realtime&Cloud Firestore) 全解析

[APP開發-使用Swift] 21-2. Firebase - 新增

Firebase教學:如何實作上傳圖片功能與遠端存取


上一篇
Firebase來幫忙登入畫面 Day 11
下一篇
資料不夠,API來湊 Day13
系列文
一個令我自豪的App完成之路32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言